package com.yonyou.ucf.mdf.app.isvdxq.utils;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class MyTool {
    /**
     * 获取当前系统时间
     */
    public static long timeGen() {
        return System.currentTimeMillis();
//        Date currentTime = new Date();
//        long timestamp = currentTime.getTime();
//        return timestamp;
    }

    /**
     * 返回项目根目录
     * @return
     */
    public static String getRootPath() {
        String path = System.getProperty("user.dir");
        return path;
    }
    public static void safeFolderPath(String folderPath){
        // 创建File对象
        File folder = new File(folderPath);

        // 判断文件夹是否存在
        if (folder.exists() && folder.isDirectory()) {
        } else {
            folder.mkdirs();
        }
    }

    /**
     * 秒
     * @param s
     * @return
     */
    public static long timeGen(int s) {
        return System.currentTimeMillis() + s*1000;
    }

    public static String GUID() {
        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }

    public static String GenerateTime() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    public static String GenerateTime(String farmatString) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(farmatString);
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    //length=21+(key.length)
    public static String GenerateEpc(String key) {
        String dateString = GenerateTime("yyyyMMddHHmmssSSS");
        String randomString = RandomString();
        return key + dateString + randomString;
    }

    //1000~9999
    public static String RandomString() {
        int max = 10000;
        int min = 1000;
        Random random = new Random();
        String randomString = "" + (random.nextInt(max - min) + min);
        return randomString;
    }

    /**
     * 时间计算
     *
     * @param str    时间字符串
     * @param format 时间格式
     * @param type   Calendar内置常量 Calendar.MINUTE
     * @param num    加减值
     * @return
     * @throws ParseException
     */
    public static String timeCalculate(String str, String format, int type, int num) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date d = sdf.parse(str);
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        c.add(type, num);
        return sdf.format(c.getTime());
    }

    /**
     * 获取两个时间差
     *
     * @param time1
     * @param time2
     * @param format
     * @return
     * @throws ParseException
     */
    public static long timeDiff(String time1, String time2, @RequestParam(defaultValue = "yyyy-MM-dd HH:mm:ss") String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date timeObj1 = sdf.parse(time1);
        Date timeObj2 = sdf.parse(time2);
        return Math.abs(timeObj2.getTime() - timeObj1.getTime());
    }

    /**
     * 生成随机Long Id
     */
    public static String getRandomId() {
//        long id = IdManager.getInstance().nextId();
//        return String.valueOf(id);
        //return Long.valueOf(timeGen()).toString();
        SecureRandom secureRandom = new SecureRandom();
        Long secureRandomLong = secureRandom.nextLong();
        return String.valueOf(secureRandomLong);
    }
    public static long GenerateRandomId(){
        return Long.parseLong(getRandomId());
    }
    /**
     * Token 验证 MD5(tenantId+yyyyMMdd)
     * 私有Token验证方案
     *
     * @param key
     * @param tenantId
     * @return
     */
    public static boolean checkToken(String key, String tenantId) {
        Date currentTime = new Date();
        String mykey = Base64Util.Base64ToString(key, 6);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateString = formatter.format(currentTime);
        String keySafe = DigestUtils.md5Hex(tenantId + dateString);
        if (mykey.equals(keySafe)) return true;
        return false;
    }

    /**
     * 用友Meme 备注规则
     * 提交 batchno_dxq 回写 batch_no
     * @param batchno_dxq
     * @param countEPC
     * @return
     */
    public static String makeMemo(String batchno_dxq, int countEPC) {
        return String.format("%s|epc%s", batchno_dxq, countEPC);
    }

    public static String makeMemoForDetail(String tableName, String id, String epccode) {
        return String.format("%s|%s|%s", tableName, id, epccode);
    }

    /**
     * 生成 Dxq 安全Token
     *
     * @param tenantId
     * @return
     */
    public static String GenerateDxqToken(String tenantId) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateString = formatter.format(currentTime);
        String keySafe = DigestUtils.md5Hex(tenantId + dateString);
        String key = Base64Util.ToBase64(keySafe, 6);
        return keySafe;
    }

    /**
     * 生成德鑫泉私有提交批次
     *
     * @return
     */
    public static String GenerateBatchnoDXQ(String ordertype) {
        String batchNum = GenerateCode();
        StringBuilder se = new StringBuilder(batchNum);
        String picicode = se.insert(14, ordertype).toString();
        return picicode;
    }

    public static String GenerateCode() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateString = formatter.format(currentTime);
        int max = 10000;
        int min = 1000;
        Random random = new Random();
        String fileName = "" + (random.nextInt(max - min) + min + 1);
        dateString = dateString + fileName;
        return dateString;
    }

    public static HashMap<String, String> getAllHeaders(HttpServletRequest request) {
        HashMap<String, String> map = new HashMap<String, String>();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }

    // getParameterMap 获取请求参数
    public static Map<String, Object> myPostParams(Map<String, String[]> map) {
        Map<String, Object> params = new HashMap<String, Object>();
        //遍历
        for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
            Map.Entry element = (Map.Entry) iter.next();
            String strKey = (String) element.getKey();  //key值
            String[] value = (String[]) element.getValue();//value,数组形式
            Object strVal = (Object) String.join(",", value);
            params.put(strKey, strVal);
        }
        return params;
    }

    public static String jsonToQueryUrl(String paramJSON) {
        StringBuilder param = new StringBuilder("?");
        Map paramMap = (Map) JSONObject.parse(paramJSON);
        for (Object entry : paramMap.entrySet()) {
            param.append(((Map.Entry) entry).getKey());
            param.append("=");
            param.append(((Map.Entry) entry).getValue());
            param.append("&");
        }
        return param.toString();
    }

    public static String paramJson(String paramIn) {
        paramIn = paramIn.replaceAll("=", "\":\"");
        paramIn = paramIn.replaceAll("&", "\",\"");
        return "{\"" + paramIn + "\"}";
    }

    public static String paramJsonByQueryUrl(String paramStr) {
        String[] params = paramStr.split("&");
        JSONObject obj = new JSONObject();
        for (int i = 0; i < params.length; i++) {
            String[] param = params[i].split("=");
            if (param.length >= 2) {
                String key = param[0];
                StringBuilder value = new StringBuilder();
                value.append(param[1]);
                for (int j = 2; j < param.length; j++) {
                    value.append("=").append(param[j]);
                }
                try {
                    obj.put(key, value.toString());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
        return obj.toString();
    }

    public static Map<String, Object> paramUrl2Map(String paramStr) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        String[] params = paramStr.split("&");
        for (int i = 0; i < params.length; i++) {
            String[] param = params[i].split("=");
            if (param.length >= 2) {
                String key = param[0];
                StringBuilder value = new StringBuilder();
                value.append(param[1]);
                for (int j = 2; j < param.length; j++) {
                    value.append("=").append(param[j]);
                }
                try {
                    hashMap.put(key, value.toString());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
        return hashMap;
    }

    /**
     * sql注入过滤检测
     *
     * @param str
     * @return
     */
    public static boolean sql_inj(String str) {
        String inj_str = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
        String inj_stra[] = inj_str.split("\\|");
        for (int i = 0; i < inj_stra.length; i++) {
            if (str.indexOf(inj_stra[i]) >= 0) {
                return true;
            }
        }

        return false;
    }

    /**
     * Bean实体赋值
     *
     * @param from
     * @param to
     * @return
     */
    public static Object convertBean2Bean(Object from, Object to) {
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(to.getClass());
            PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();

            for (PropertyDescriptor p : ps) {
                Method getMethod = p.getReadMethod();
                Method setMethod = p.getWriteMethod();
                if (getMethod != null && setMethod != null) {
                    try {
                        Object result = getMethod.invoke(from);
                        setMethod.invoke(to, result);
                    } catch (Exception e) {
                        // 如果from没有此属性的get方法，跳过
                        continue;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return to;
    }

    /**
     * 实体转换
     *
     * @param from
     * @param clz
     * @param <T>
     * @return
     */
    public static <T> T convertBean2Bean(Object from, Class<T> clz) {
//        String jsonStr = new Gson().toJson(from);
//        return new Gson().fromJson(jsonStr, clz);
        return JSONObject.parseObject(JSONObject.toJSONString(from), clz);
//        return MyBeanUtils.transform(from, clz);
    }

    /**
     * 把List<Object[]>转换成List<T>
     */
    public static <T> List<T> objectToBean(List<Object[]> objList, Class<T> clz) throws Exception {
        if (objList == null || objList.size() == 0) {
            return null;
        }

        Class<?>[] cz = null;
        Constructor<?>[] cons = clz.getConstructors();
        for (Constructor<?> ct : cons) {
            Class<?>[] clazz = ct.getParameterTypes();
            if (objList.get(0).length == clazz.length) {
                cz = clazz;
                break;
            }
        }

        List<T> list = new ArrayList<T>();
        for (Object[] obj : objList) {
            Constructor<T> cr = clz.getConstructor(cz);
            list.add(cr.newInstance(obj));
        }
        return list;
    }

    public static <T> List<T> jsonToList(String json, Class<List<T>> clazz) {
        Gson gson = new Gson();
        List<T> array = gson.fromJson(json, clazz);
        return array;
    }

    public static <T> List<T> convertBeanList(List<?> objList, Class<T> clz) {
        List<T> res = new ArrayList<>();
        objList.forEach(item -> {
            res.add(convertBean2Bean(item, clz));
        });
        return res;
    }

    public static <T> T getBean(String reqString, Type type) {
        return new Gson().fromJson(reqString, type);
    }

    public static List removeDuplite(List list) {
        HashSet h = new HashSet(list);
        list.clear();
        list.addAll(h);
        return list;
    }

    /**
     * 移除最后一个符号，字符串转换成为List
     *
     * @param stringContent 字符串
     * @param separator     分隔符
     * @return 返回List
     */
    public static List<String> StringRemoveLastSymbolToList(String stringContent, String separator) {
        stringContent = stringContent.substring(0, stringContent.length() - 1);
        String[] strArr = stringContent.split(separator);
        List<String> stringList = new ArrayList<>();
        for (String item : strArr) {
            stringList.add(item);
        }
        return stringList;
    }


    public static String removeCharAt(String s, int pos) {
        return s.substring(0, pos) + s.substring(pos + 1);
    }

    public static String insertCharAt(String s, int pos, char c) {
        return s.substring(0, pos) + c + s.substring(pos);
    }
    /*
     * 从数组中找出元素值的下标，通过函数的返回值返回
     * @param int[]arr1 要查找数据的数组
     * @param int value 要查询的数据
     * @return 返回找到的下标 如果没有找到 就返回-1
     * */
    public static int findIndex(int[] arr1, int value){
        int index = -1;

        // 1.首先要进行参数合法性判断
        if(null == arr1 || arr1.length == 0){
            System.out.println("参数不合法!");
            return index;
        }

        // 进行数组查找操作
        for(int i = 0; i<arr1.length; i++){
            if(arr1[i] == value){
                index = i;
                break;
            }
        }

        return index;
    }
}
